package com.zj.common.expand

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import com.zj.common.http.RetrofitDSL
import kotlinx.coroutines.*


fun <T> CoroutineScope.retrofit(dsl: RetrofitDSL<T>.() -> Unit) {
    launch {
        val retrofitDSL = RetrofitDSL<T>()
        retrofitDSL.dsl()
        try {
            val result = retrofitDSL.api.invoke()
            when (result.errorCode) {
                0 -> {
                    retrofitDSL.onSuccess?.invoke(result)
                }
                else -> {
                    retrofitDSL.onFailed?.invoke(result.errorMsg, result.errorCode)
                }
            }
        } catch (e: Exception) {
            retrofitDSL.onFailed?.invoke(e.message.toString(), -1)
        } finally {
            retrofitDSL.onComplete?.invoke()
        }
    }

}

/**
 * 运行在主线程的协程
 */
fun main(block: suspend CoroutineScope.() -> Unit): Job {
    return GlobalScope.launch(Dispatchers.Main) {
        block.invoke(this)
    }
}


/**
 * 运行在io线程的有返回值的协程
 */
fun <T> wait(block: suspend CoroutineScope.() -> T): Deferred<T> {
    return GlobalScope.async(Dispatchers.IO) {
        block.invoke(this)
    }
}


/**
 * io协程，运行在io线程
 */
fun io(block: suspend CoroutineScope.() -> Unit): Job {
    return GlobalScope.launch(Dispatchers.IO) {
        block.invoke(this)
    }
}
/**
 * 可以绑定生命周期的io协程
 */
fun LifecycleOwner.io(block: suspend CoroutineScope.() -> Unit): Job {
    val supervisorJob = SupervisorJob()
    CoroutineScope(Dispatchers.IO + supervisorJob).launch {
        block.invoke(this)
    }
    lifecycle.addObserver(object : LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        fun onDestroy() {
            supervisorJob.cancel()
            lifecycle.removeObserver(this)
        }
    })
    return supervisorJob
}

/**
 * 可以绑定生命周期的main协程
 */
fun LifecycleOwner.main(block: suspend CoroutineScope.() -> Unit): Job {
    val supervisorJob = SupervisorJob()
    CoroutineScope(Dispatchers.Main + supervisorJob).launch {
        block.invoke(this)
    }
    lifecycle.addObserver(object : LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        fun onDestroy() {
            supervisorJob.cancel()
            lifecycle.removeObserver(this)
        }
    })
    return supervisorJob
}
